const random = require("./random");
const deepcopy = require("./deepcopy");

let fn = function(){
    this._EffectAudioIds = {};
};

fn.prototype = {
    playPop( node , cb , timmer){
        if(!node || !cc ) {
            cb && cb();
            return this;
        };
        node.runAction(
            cc.sequence(
                cc.scaleTo( .06 , 1.5),
                cc.scaleTo( .1 , .9 ),
                cc.scaleTo( .06 , 1 ),
                cc.scaleTo( timmer ? timmer : 0 , 1 ),
                cc.callFunc(()=>{
                    cb && cb();
                })
            )
        );

        return this;
    },

    playHuxi( node , cb , flag ){
        if(!node || !cc ) {
            cb && cb();
            return this;
        };
        //是否开启呼吸，默认开启
        flag = this.selectValue( flag , true );

        node.__mHuxiAnimate && node.__mHuxiAnimate.stop();

        if(flag){
            node.__mHuxiAnimate = cc.tween(node)
            .to(1 , {scale:1.1})
            .to(1 , {scale:1})
            .repeatForever()
            .start();
        }

        return;
    },

    playPop_plus( node , cb , timmer , max , stscl){
        max = max || 0.5;
        if(!node || !cc ) {
            cb && cb();
            return this;
        };
        let old = stscl || node.scale;
        node.runAction(
            cc.sequence(
                cc.scaleTo( .06 , old+max),
                cc.scaleTo( .1 , old-.1 ),
                cc.scaleTo( .06 , old ),
                cc.scaleTo( timmer ? timmer : 0 , old ),
                cc.callFunc(()=>{
                    cb && cb();
                })
            )
        );

        return this;
    },

    createFrameNode( frame ){
        let node = new cc.Node();
        node.addComponent(cc.Sprite);
        this.setSprite( node , frame );
        return node;
    },

    showUI( node , cb ){
        if(!node || !cc ) {
            cb && cb();
            return this;
        };
        //node.scale = 0;
        node.runAction(
            cc.sequence(
                cc.scaleTo( .06 , 0),
                cc.scaleTo( .06 , 1.5),
                cc.scaleTo( .1 , .9 ),
                cc.scaleTo( .06 , 1 ),
                cc.callFunc(()=>{
                    cb && cb();
                })
            )
        );

        return this;
    },

    random(){
        return random.getRandom.apply(random , arguments );
    },

    select(){
        return this.selectValue.apply( this , arguments);
    },
    //返回参数列表中第一个有定义的值
    selectValue(){
        let arr = Array.prototype.slice.call(arguments);
        for(let i in arr){
            if( typeof arr[i] != 'undefined' ){
                return arr[i];
            }
        }
        return undefined;
    },

    timestamp(){
        return (new Date()).valueOf();
    },

    trimAll( str ){
        str = this.selectValue( str , "");
        str = str.replace(/\s*/g , "");
        return str;
    },

    transArr( str , fg ){
        fg = fg || ".";
        str = this.select( str , "");
        str = this.trimAll(str);
        return str.split( fg );
    },

    is(){
        let args = Array.prototype.slice.call(arguments),
            flg = true , last ;
        for(let i in args){
            if(last && last !== args[i]){
                return false;
            }
            last = args[i]
        }
        return flg;
    },

    //判断v 是否在指定模式当中
    isModelValue( v , ov ){
        let re = false;
        if(this.isType(ov,"Array")){
            for(let i in ov){
                if(ov[i]===v){
                    return true;
                }
            }
        }else{
            re = (v===ov);
        }
        return re;
    },

    isType( o , typestr ){
        return Object.prototype.toString.call( o ).substr(8,typestr.length) == typestr;
    },

    type(o){
        let typestr = Object.prototype.toString.call( o ),
            starti = typestr.indexOf(" ")+1;
        
        return typestr.substr( starti , typestr.length-starti-1);

    },

    inArray( arr , v){
        arr = arr || [];
        return (arr.indexOf(v) >= 0);
    },

    changeSizeArr( v ){
        v = this.selectValue( v , 0);
        let r = this.isType( v , "Array" ) ? v : [ v , v];
        return r;
    },
    setLabel( label , txt ){
        let lb = label.getComponent(cc.Label);
        lb.string = String(txt);
        return this;
    },
    //改变node的纹理
    setSprite( node , sprite , size ){
        if(!node /*|| !sprite*/) return this;
        let s = node.getComponent(cc.Sprite);
        if(!s){
            node.addComponent(cc.Sprite);
            s = node.getComponent(cc.Sprite);
        }
        s.spriteFrame = sprite;
        if(size && size.length>0){
            this.setNodeSize( node , size );
            // let h = size[1];
            // let w = size[0];
            // if(!h){
            //     h = sprite._originalSize.height * (size[0]/sprite._originalSize.width);
            // }
            // if(!w){
            //     w = sprite._originalSize.width * (size[1]/sprite._originalSize.height);
            // }
            // node.width = w;
            // node.height = h;
        }
        return this;
    },

    setNodeSize( node , size ){
        let s = node.getComponent(cc.Sprite);
        let sprite = s ? s.spriteFrame : null;

        let w = size[0];
        let h = size[1];
        let nw = sprite && sprite._originalSize ? sprite._originalSize.width : node.width, 
            nh = sprite && sprite._originalSize ? sprite._originalSize.height : node.height;

        if(!h){
            h = nh * (size[0]/nw);
        }
        if(!w){
            w = nw * (size[1]/nh);
        }
        node.width = w;
        node.height = h;
        return {w:w,h:h}
    },
    //相关audio方法:

    getClipPlayingList(clip){
        let reList = this._EffectAudioIds[clip];
        if(!reList) reList = this._EffectAudioIds[clip] = [];
        return reList;
    },
    pushClipId( clip , id){
        let arr = this.getClipPlayingList( clip );
        arr.push(id);
    },
    removeAudioIdByClip( clip , id ){
        let arr = this.getClipPlayingList(clip);
        for(let i =0; i<arr.length ; i++){
            if(arr[i] == id){
                arr.splice(i,1);
                break;
            }
        }
    },

    playMusic( audioClip , loop ,  isStopOther , isdelus){        
        let clip = this.isType(audioClip , "String") ? audioClip : audioClip.nativeUrl;
        if( clip && ( Gloab.get('userAudioOpen') || isdelus)){
            if(isStopOther){
                cc && cc.audioEngine.stopAll();
            }
            return cc && cc.audioEngine.playMusic( clip , !!loop);
        }
    },

    stopMusic( clipId ){
        if(!clipId){
            cc && cc.audioEngine.stopAll();
        }else{
            cc && cc.audioEngine.stopMusic( clipId );
        }
    },

    playEffect( clipObj , ismust ){
        let clip = this.isType(clipObj , "String") ? clipObj : clipObj;
        let clipStr = this.isType(clipObj , "String") ? clipObj : clipObj.nativeUrl;
        let audioList  = this.getClipPlayingList(clipStr);
        let fn = ( c , i)=>{
            this.removeAudioIdByClip( c , i);
        }
        if( Gloab.get('userEffectOpen') || ismust ){
            if(audioList.length < 5){
                let id = cc.audioEngine.playEffect(clip);
                this.pushClipId( clipStr , id);
                cc.audioEngine.setFinishCallback( id , ()=>{
                    fn( clipStr , id);
                });
            }
        }
    },

    randomsign(){
        return this.random(1,10)>5 ? -1 : 1;
    },
    
//合并两个数组，去重  
    concat(){
        let args = Array.prototype.slice.call(arguments);
        let isQC = this.isType( args[args.length-1] , "Boolean") ? args[args.length-1] : true;
        
        let arr = args[0].concat();
        for(let i=1; i<args.length ; i++){
            if(this.isType( args[i] , "Array")){
                if(isQC){
                    for(let t in args[i]){
                        if(arr.indexOf( args[i][t] )<0 ){ 
                            arr.push(args[i][t]) 
                        }
                    }
                }else{
                    arr = arr.concat( args[i] );
                }
            }

        }
        return arr;  
    },


    //about event
    gloabTrigger(){

    },

    trigger( node ,  evname , isBubbing , data){
        node = node || $G.get("rootCanvas");
        let event =  new cc.Event.EventCustom(evname , !!isBubbing) ;
        data && event.setUserData(data);
        node.dispatchEvent ( event );
    },

    numberFormat( num ){
        let str = String(num) ,
            nStr = "";
        for(let i=str.length-1; i>=0; i--){
            nStr = str[i] + nStr;
            (i<(str.length-1) && i>0 && (str.length-(i))%3 == 0 ) && (nStr = "," + nStr);
        }
        return nStr;
    },
    getNumberFrmStr(str){
        str = str || "0";
        str = str.replace(/\,/g , "");
        return parseInt(str);
    },

    find(){
        return this.findChildNode.apply( this , arguments);
    },

    findChildNode(str , rootNode ){
        str = str || "";
        str = str.replace(/\s/g , "");
        str = str.replace(/\>{2,}/g , ">")
        let arr = str.split(">") ,
            node = rootNode || Gloab.get("rootCanvas");
        let fn = (i)=>{
            node = (node && node.getChildByName && arr[i]) ? node.getChildByName(arr[i]) : null;
            if( !node || !arr[i] || i==(arr.length-1)){
                return node;
            }else{
                return fn(i+1)
            }
        }

        return fn(0);
    },

    getScr( node , re){
        let coms = node.getComponents(cc.Component);
        for(let i=0; i<coms.length;i++){
            let name = (coms[i].__proto__ && coms[i].__proto__.__classname__) || "cc.";
            if( name.indexOf("cc.") < 0 ){
                if(re && this.isType(re , "Array")){
                    re.push(coms[i]);
                }else if( re && this.isType(re , "String") ){
                    if(name == re){
                        return coms[i];
                    }
                }else{
                    return coms[i];
                }
            }
        }
        return null;
    },

    numberToWord( num ){
        const t = [
            "零","一","二","三","四","五","六","七","八","九"
        ];

        if(num<10){
            return t[num]
        }else{
            return "";
        }
    },

    //获取日期戳 int 如：20190809 , 20190912
    getDateStmp( date ){
        date = date || new Date();
        let d = date , re = "";
        let yyyy = d.getFullYear(),
            mm = d.getMonth()+1,
            dd = d.getDate();
        yyyy = String(yyyy);
        mm = mm<10 ? "0"+ String(mm) : String(mm);
        dd = dd<10 ? "0"+ String(dd) : String(dd);

        re = new Date(yyyy +"-"+ mm +"-"+ dd);
        return re;
    },

    dateCha( d , d1){
        d = new Date(d);
        d1 = new Date(d1);
        return (d-d1)/(3600*24)/1000;
    },

    recordChildren( node , name ){
        let re = {};
        if(!node) return re;

        if(!name){
            for(let i in node.children){
                let child = node.children[i];
    
                re[child.name] = {
                    node :child,
                    pos : child.getPosition(),
                    size : child.getContentSize(),
                    scale : child.scale,
                    opacity : child.opacity,
                    zIndex : child.zIndex
                }
            }
        }else{
            let names = this.isType(name , "Array") ? name : [name];
            for(let i=0; i<names.length; i++){
                let child = this.find( names[i] , node );
                if(child){
                    re[child.name] = {
                        node :child,
                        pos : child.getPosition(),
                        size : child.getContentSize(),
                        scale : child.scale,
                        opacity : child.opacity,
                        zIndex : child.zIndex
                    }
                }
            }
        }


        return re;
    },

    getMaxMinzindex( node ){
        let max = 0 , min = 100000;
        for(let i in node.children){
            let child = node.children[i];
            max = max<child.zIndex ? child.zIndex : max;
            min = min>child.zIndex ? child.zIndex : min;
        }
        return {
            max,
            min
        }
    },

    clone( opt ){
        return deepcopy(opt);
    },

    vibrate( long , cb ){
        long = this.selectValue( long , false );
        let api = $G.get("apiObject");
        if(!api) return;
        if(!long && api.vibrateShort){
            api.vibrateShort({
                complete : ()=>{
                    cb && cb();
                    console.log(arguments)
                    console.log("dddd")
                }
            })
        }else if(api.vibrateLong){
            api.vibrateLong({
                complete : ()=>{
                    cb && cb();
                    console.log(arguments)
                    console.log("ddddlll")
                }
            })
        }
    },

    //以指定pos为中心， 计算出元素应该所在位置
    //中心点 , 第几个元素 , 元素尺寸大小 , 每行个数 , 总个数
    compListShowPos(  toPos , index , size , per , totalN ){
        let repos = {} ;
        const lineNo = Math.ceil((index)/per), 
              vertNo = (index)%per ,
              tLine = Math.ceil((totalN)/per),
              paddingw = size.pw ? size.pw : 0 ,
              paddingh = size.ph ? size.ph : 0 ,
              curLine = Math.ceil(index/per),
              lineIndex = index%per==0 ? per : index%per;
        //if( tLine < 2 ){
        let lineNum = curLine < tLine ? 
                      per : 
                      (totalN%per==0 ? per : totalN%per);
        //console.log("%s行/ %s个/ %s" , curLine , lineIndex , lineNum );
        let bside = lineNum/2 , bside_h = tLine/2,
            juli = (lineIndex-bside)-1,
            juli_h = (curLine - bside_h)-1;  
            juli_h = -juli_h;

        repos.x = toPos.x +  size.w * juli + juli*paddingw + paddingw/2 + size.w/2;
        repos.y = toPos.y +  size.h * juli_h + juli_h*paddingh + paddingh/2 + size.h/2;
        //}

        return repos;
    },

    //计算一个列表 沿中心点按对称序列排列所需的关键值
    //中心点值 ， 所在index , 间隔值， 元素个数
    compListPoxV( pv , i , jg , len , fx ){
        fx = fx || 1;
        let ou = len%2==0;
        let ofset = ou ?  jg/2 : 0;
        let md = len/2 ,
            jl = i-md;
        if(ou){
            let jlabs = Math.abs(jl);
            return pv + ( (jl==0?1:(jl/jlabs)) * (jl<0?jlabs-1:jlabs) *jg + ofset*(jl==0?1:(jl/jlabs)) );
        }else{
            jl = Math.ceil(jl);
            return pv + ( ( jl*jg ) * fx );
        }
        // let re = ( jl*jg - (jl<0?-jg:0) - ofset) * fx;
        // re = re==0 ? 0 : re;
        // return re;
    },

    getAngle( p ) {
        let x = p.x , y=p.y;
        var a = Math.atan2(y, x);
        var ret = a * 180 / Math.PI; //弧度转角度，方便调试
        if (ret > 360) {
            ret -= 360;
        }
        if (ret < 0) {
            ret += 360;
        }
        return ret;
    },

    getAnglePos(pos , rotation , len ){
        let topos = cc.v2( len*Math.cos( this.toRota( rotation )) , len*Math.sin( this.toRota( rotation ) )) ;
        return pos.add( topos );
    },

    getRota( p ){
        let x = p.x , y=p.y;
        var a = Math.atan2(y, x);
        return a;
    },

    toAngle( a ){
        return a * 180 / Math.PI;
    },

    toRota( angle ){
        return angle*Math.PI/180;
    },

    delay( fn , params ,  delay , scope ){
        params = params || [];
        if( !this.isType(params , "Array")) params = [params];

        if(delay){
            let node = this._getTmpNode();
            node.parent = cc.find("Canvas");

            cc.tween( node )
            .to(delay,{opacity:255})
            .call(()=>{
                if(scope){
                    fn.call( scope , ...params)
                }else{
                    fn(...params);
                }
                this._putTmpNode(node);
            })
            .start();
        }else{
            if(scope){
                fn.call( scope , ...params)
            }else{
                fn(...params);
            }
        }
    },

    //获得一个临时空node
    _getTmpNode(){
        this.__tmpNodePool = this.__tmpNodePool || new cc.NodePool("tools_tmp_node_pool");
        let node = this.__tmpNodePool.get();
        node = node || new cc.Node("_toolsTmpNode");
        return node;
    },

    _putTmpNode( node ){
        if(!node) return;
        this.__tmpNodePool = this.__tmpNodePool || new cc.NodePool("tools_tmp_node_pool");
        this.__tmpNodePool.put(node);
    }

}

if(!window.$T){
    window.Tools = window.$T = new fn();
}

module.exports = Tools;